﻿using System;
using System.Windows;
using Sinacor.Infra.UI.Controls.SmartClient;
using Sinacor.UI.Bovespa.Contabil.Presenter;
using System.Windows.Threading;

namespace Sinacor.UI.Bovespa.Contabil.View.SmartClient
{
    /// <summary>
    /// Interaction logic for CadastroEventoContabil.xaml
    /// </summary>
    public partial class CadastroEventoContabil : SinacorWindow, ICadastroEventoContabil
    {
        #region Construtor

        /// <summary>
        /// Construtor
        /// </summary>
        public CadastroEventoContabil()
        {
            InitializeComponent();

            // Inicialize a presenter no construtor
            this.cadastroEventoContabilPresenter = new Presenter.CadastroEventoContabil(this);

            // Configure a presenter no DataContext da janela (para facilitar os bindings)
            this.DataContext = this.cadastroEventoContabilPresenter;

            this.dataEventos.NewItemType = typeof(Model.EventoContabil);

            this.AfterInitialize += new RoutedEventHandler(CadastroEventoContabil_AfterInitialize);
        }

        #endregion

        #region Presenter

        /// <summary>
        /// Propriedade com a presenter da view
        /// </summary>
        public Presenter.CadastroEventoContabil cadastroEventoContabilPresenter { get; set; }

        #endregion

        #region Atributos

        private bool codigoInformado = false;
        private bool descricaoInformado = false;

        private bool _generatingFocus = false;
        private bool _firstValidation = true;

        #endregion

        #region Métodos Privados

        /// <summary>
        /// Exibir mensagens de informação
        /// </summary>
        /// <param name="resourceKey">ResourceKey com a mensagem</param>
        private void ExibirMensagemInformacao(string resourceKey)
        {
            SinacorMessageBox.Show(FindResource(resourceKey).ToString(), SinacorMessageBoxImage.Information);
        }

        /// <summary>
        /// Exibir mensagens de exclamação
        /// </summary>
        /// <param name="resourceKey">ResourceKey com a mensagem</param>
        private void ExibirMensagemExclamacao(string resourceKey)
        {
            SinacorMessageBox.Show(FindResource(resourceKey).ToString(), SinacorMessageBoxImage.Exclamation);
        }

        #endregion

        #region ICadastroEventoContabil Members

        /// <summary>
        /// Realizar o updatetarget no datagrid de eventos contábeis
        /// </summary>
        public void AtualizarEventoContabil()
        {
            dataEventos.UpdateTarget(SinacorDataGrid.ItemsSourceProperty);
        }

        /// <summary>
        /// Exibir mensagem de confirmação de exclusão de um evento contábil
        /// </summary>
        /// <returns>bool</returns>
        public bool ConfirmarExclusaoEventoContabil()
        {
            if (SinacorMessageBox.Show(FindResource("Bovespa.Contabil.Message.DesejaExcluirEvento").ToString(), SinacorMessageBoxButton.YesNo, SinacorMessageBoxImage.Question)
                == SinacorMessageBoxResult.Yes)
                return true;

            return false;
        }

        /// <summary>
        /// Informar alteração realizada com sucesso
        /// </summary>
        public void InformarAlteracaoSucesso()
        {
            ExibirMensagemInformacao("Bovespa.Contabil.Message.AlteracaoSucesso");
        }

        /// <summary>
        /// Informar campo código obrigatório
        /// </summary>
        public void InformarCodigoObrigatorio()
        {
            ExibirMensagemExclamacao("Bovespa.Contabil.ExceptionMessage.CodigoEventoObrigatorio");
        }

        /// <summary>
        /// Informar campo descrição obrigatório
        /// </summary>
        public void InformarDescricaoObrigatoria()
        {
            ExibirMensagemExclamacao("Bovespa.Contabil.ExceptionMessage.DescricaoObrigatoria");
        }

        /// <summary>
        /// Informar exclusão realizada com sucesso
        /// </summary>
        public void InformarExclusaoSucesso()
        {
            ExibirMensagemInformacao("Bovespa.Contabil.Message.ExclusaoRealizadaSucesso");
        }

        /// <summary>
        /// Informar inclusão realizada com sucesso
        /// </summary>
        public void InformarInclusaoSucesso()
        {
            ExibirMensagemInformacao("Bovespa.Contabil.Message.InclusaoSucesso");
        }

        /// <summary>
        /// Informar que não existem dados cadastrados na pesquisa de eventos contábeis
        /// </summary>
        public void InformarNaoExistemDadosCadastrado()
        {
            ExibirMensagemExclamacao("Bovespa.Contabil.Message.NaoExistemDadosCadastrado");
        }

        /// <summary>
        /// Informar selecione um evento contábil no datagrid
        /// </summary>
        public void InformarSelecioneEventoContabil()
        {
            ExibirMensagemExclamacao("Bovespa.Contabil.Message.SelecioneEventoContabil");
        }

        /// <summary>
        /// Atribuir o foco no campo código do datagrid
        /// </summary>
        public void AtribuirFocoCodigo()
        {
            dataEventos.GetCurrentRow().Cells["CD_EVECON"].Focus();
        }

        /// <summary>
        /// Atribuir o foco no campo descrição do datagrid
        /// </summary>
        public void AtribuirFocoDescricao()
        {
            dataEventos.GetCurrentRow().Cells["DS_EVECON"].Focus();
        }

        #endregion

        #region Eventos

        #region AfterInitialize

        /// <summary>
        /// Event Handler disparado após a inicialização dos controles
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">RoutedEventArgs</param>
        private void CadastroEventoContabil_AfterInitialize(object sender, RoutedEventArgs e)
        {
            this.ShowUserWaitingProcess();
            this.cadastroEventoContabilPresenter.Inicializar();
            this.HideUserWaitingProcess();
        }

        #endregion

        #region DataGrid

        /// <summary>
        /// Evento de exclusão do datagrid
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">CancelItemsEventArgs</param>
        private void dataEventos_Deleting(object sender, CancelItemsEventArgs e)
        {
            if (e.OriginalSource is SinacorDataGrid)
            {
                if (dataEventos.SelectedItem != null)
                {
                    this.ClearServiceErrors();

                    if (this.ConfirmarExclusaoEventoContabil())
                    {
                        this.ShowUserWaitingProcess();

                        if (!this.cadastroEventoContabilPresenter.ExcluirEventoContabil(this.dataEventos.SelectedItem as Model.EventoContabil))
                            e.Cancel = true;

                        HideUserWaitingProcess();

                        this.ClearChanges();
                    }
                    else
                    {
                        e.Cancel = true;
                        e.Handled = true;
                    }
                }
            }
        }

        /// <summary>
        /// Evento inicial de inserção de uma nova linha no datagrid
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">CancelItemEventArgs</param>
        private void dataEventos_BeingInserted(object sender, CancelItemEventArgs e)
        {
            dataEventos.Columns[0].IsRequired = true;
            dataEventos.GetInsertionRow().Cells[0].Focus();
            dataEventos.Columns[2].AllowInsert = true;
            ((Model.EventoContabil)dataEventos.EditItem).UtilizaMunicipio = true;
        }

        /// <summary>
        /// Evento inicial de modo de edição do datagrid
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="e">CancelItemEventArgs</param>
        private void dataEventos_BeingUpdated(object sender, CancelItemEventArgs e)
        {
            dataEventos.GetCurrentRow().Cells[1].Focus();
            dataEventos.Columns[2].AllowUpdate = true;
        }

        /// <summary>
        /// Evento de inserção de um novo evento contábil
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">CancelItemEventArgs</param>
        private void dataEventos_EndingInsert(object sender, CancelItemEventArgs e)
        {
            if (e.OriginalSource is SinacorDataGrid)
            {
                if (dataEventos.GetInsertionRow() != null)
                {
                    this.ClearServiceErrors();

                    this.ShowUserWaitingProcess();

                    Model.EventoContabil model = (Model.EventoContabil)this.dataEventos.EditItem;

                    if (model.UtilizaMunicipio == null)
                        model.UtilizaMunicipio = false;

                    if (!cadastroEventoContabilPresenter.IncluirEventoContabil(model))
                    {
                        e.Cancel = true;
                        e.Handled = true;
                    }
                    else
                    {
                        this.ClearChanges();
                        dataEventos.Columns[2].AllowInsert = false;
                        dataEventos.Columns[2].AllowUpdate = false;
                    }

                    this.HideUserWaitingProcess();
                }
            }
        }

        /// <summary>
        /// Evento de alteração de um evento contabil
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">CancelItemEventArgs</param>
        private void dataEventos_EndingUpdate(object sender, CancelItemEventArgs e)
        {
            if (e.OriginalSource is SinacorDataGrid)
            {
                if (this.dataEventos.EditItem != null)
                {
                    this.ClearServiceErrors();

                    this.ShowUserWaitingProcess();

                    if (!this.cadastroEventoContabilPresenter.AlterarEventoContabil((this.dataEventos.EditItem as Model.EventoContabil)))
                    {
                        this.HideUserWaitingProcess();
                        e.Cancel = true;
                        e.Handled = true;
                    }
                    else
                    {
                        this.HideUserWaitingProcess();
                        this.ClearChanges();
                    }

                    dataEventos.Columns[2].AllowUpdate = false;
                }
            }
        }

        /// <summary>
        /// Evento de cancelamento de inserção de evento contabil
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">CancelItemEventArgs</param>
        private void dataEventos_CancelingInsert(object sender, CancelItemEventArgs e)
        {
            dataEventos.Columns[2].AllowInsert = false;
            dataEventos.Columns[2].AllowUpdate = false;
            this.ClearServiceErrors();
        }

        /// <summary>
        /// Evento deconcelamento de alteração de evento contabil
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">CancelItemEventArgs</param>
        private void dataEventos_CancelingUpdate(object sender, CancelItemEventArgs e)
        {
            dataEventos.Columns[2].AllowInsert = false;
            dataEventos.Columns[2].AllowUpdate = false;
            this.ClearServiceErrors();
        }

        #endregion

        private void EventValidationRule_Validating_txtDescricao(object sender, Sinacor.Infra.UI.Controls.SmartClient.Validation.ValidatingEventArgs e)
        {
            SinacorTextBox txt = (SinacorTextBox)e.Source;

            if (!_generatingFocus)
            {
                //Essa rule está gerando automaticamente duas ValidationRules/Triggers
                //sendo que a primeira não tem efeito nenhum durante a validação
                //Esse booleano faz a primeira validação ser pulada
                if (_firstValidation)
                {
                    e.Result = new System.Windows.Controls.ValidationResult(true, "Bovespa.Contabil.ExceptionMessage.DescricaoObrigatoria");
                    _firstValidation = false;
                }
                else
                {
                    _firstValidation = true;

                    if (String.IsNullOrEmpty(txt.Text.Trim()))
                    {
                        _generatingFocus = true;
                        e.Result = new System.Windows.Controls.ValidationResult(false, "Bovespa.Contabil.ExceptionMessage.DescricaoObrigatoria");

                        this.Dispatcher.BeginInvoke((Action)delegate()
                                                            {
                                                                txt.Focus();
                                                                _generatingFocus = false;
                                                            },
                                                    DispatcherPriority.Normal);
                    }
                    else
                    {
                        if (txt.HasError)
                            e.Result = new System.Windows.Controls.ValidationResult(false, "Bovespa.Contabil.ExceptionMessage.DescricaoObrigatoria");
                        else
                            e.Result = new System.Windows.Controls.ValidationResult(true, "Bovespa.Contabil.ExceptionMessage.DescricaoObrigatoria");
                    }
                }
            }
            else
            {
                if (txt.HasError)
                    e.Result = new System.Windows.Controls.ValidationResult(false, "Bovespa.Contabil.ExceptionMessage.DescricaoObrigatoria");
                else
                    e.Result = new System.Windows.Controls.ValidationResult(true, "Bovespa.Contabil.ExceptionMessage.DescricaoObrigatoria");
            }
        }

        #endregion

        private void EventValidationRule_Validating_txtCodigo(object sender, Sinacor.Infra.UI.Controls.SmartClient.Validation.ValidatingEventArgs e)
        {
            SinacorInt32TextBox txt = (SinacorInt32TextBox)e.Source;

            if (!_generatingFocus
                && !txt.Value.HasValue)
            {
                _generatingFocus = true;
                e.Result = new System.Windows.Controls.ValidationResult(false, "Bovespa.Contabil.ExceptionMessage.CodigoEventoObrigatorio");

                this.Dispatcher.BeginInvoke((Action)delegate()
                                                    {
                                                        txt.Focus();
                                                        _generatingFocus = false;
                                                    },
                                            DispatcherPriority.Normal);
            }
            else
            {
                if (txt.HasError)
                    e.Result = new System.Windows.Controls.ValidationResult(false, "Bovespa.Contabil.ExceptionMessage.CodigoEventoObrigatorio");
                else
                    e.Result = new System.Windows.Controls.ValidationResult(true, "Bovespa.Contabil.ExceptionMessage.CodigoEventoObrigatorio");
            }
        }
    }
}
